package cn.mw.cmdb.util;

import cn.mw.cmdb.enums.NewUnits;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UnitsUtil {
    /**
     * 当单位中带！号时默认不进行单位转换，否则返回一个根据单位转换过的带单位的值，String类型
     *
     * @param value
     * @param units
     * @return 返回一个带单位的值
     */

   private static final String patternKey = "###################.##";

    public static String getValueWithUnits(String value, String units) {
        if (value != null && StringUtils.isNotEmpty(value)) {
            BigDecimal bValue = new BigDecimal(value);
            if (null != units && StringUtils.isNotEmpty(units)) {
                int index = units.indexOf("!");
                if (index != -1) {
                    //含有小数点，保留两位小数
                    if (value.indexOf(".") != -1) {
                        bValue = bValue.setScale(2, BigDecimal.ROUND_HALF_UP);
                        value = bValue + units.substring(index + 1);
                    } else {
                        //不含小数点。不做单位转换但是带单位的数据
                        value = bValue + units.substring(index + 1);
                    }
                } else {
//                做单位转换但是带单位的数据
                    Map<String, String> convertedValue = getConvertedValue(bValue, units);
                    value = convertedValue.get("value") + convertedValue.get("units");
                }
            } else {
                //含有小数点，保留两位小数
                if (value.indexOf(".") != -1) {
                    value = bValue.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                }
            }
        } else {
            value = 0 + units;
        }

        return value;
    }

    /**
     * 根据单位和value值的大小，进行合适的单位转换
     *
     * @param value
     * @param units
     * @return
     */
    public static Map<String, String> getConvertedValue(BigDecimal value, String units) {
        Map<String, String> map = new HashMap<>();
        if (null != units && StringUtils.isNotEmpty(units)) {
            NewUnits infoByUnits = NewUnits.getInfoByUnits(units);
            if (infoByUnits != null && infoByUnits.getMapKey() >= 0) {
                List unitsList = NewUnits.UNITSMAP.get(infoByUnits.getMapKey());
                while (value.doubleValue() > infoByUnits.getRadix()) {
                    if (units.equals(unitsList.get(unitsList.size() - 1))) {
//                     当数值单位已经是最大时，value值还时大于infoByUnits.getRadix()，将不再循环
                        break;
                    }
                    value = value.divide(new BigDecimal(infoByUnits.getRadix()), 6, BigDecimal.ROUND_HALF_UP);
                    units = getNextUnits(units, infoByUnits.getMapKey(), true);
                    infoByUnits = NewUnits.getInfoByUnits(units);
                }
                while (0 < value.doubleValue() && value.doubleValue() < 1) {
                    if (units.equals(unitsList.get(0))) {
//                     当数值单位已经是最小时，value值还没有大于1，将不再循环
                        break;
                    }
                    value = value.multiply(new BigDecimal(infoByUnits.getRadix())).setScale(2, BigDecimal.ROUND_HALF_UP);
                    units = getNextUnits(units, infoByUnits.getMapKey(), false);
                    infoByUnits = NewUnits.getInfoByUnits(units);
                }
            }
        }
        //数值含有小数点
        if (String.valueOf(value).indexOf(".") != -1) {
            value = value.setScale(2, BigDecimal.ROUND_HALF_UP);
        }

        DecimalFormat decimalFormat = new DecimalFormat(patternKey);
        map.put("value", decimalFormat.format(value));
        map.put("units", units);
        return map;
    }

    /**
     * @param units 当前单位
     * @param key   当前单位所在的value对应的key
     * @param flag  true为当前单位右边的值，false为当前单位左边的值
     * @return 当前单位左边或右边的值
     */
    public static String getNextUnits(String units, Integer key, Boolean flag) {
        List<String> list = NewUnits.UNITSMAP.get(key);
        int index = 0;
        if (list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (units.equals(list.get(i))) {
                    index = i;
                }
            }
        }
        if (flag) {
            return list.get(index + 1);
        } else {
            if (index > 0) {
                return list.get(index - 1);
            } else {
                return list.get(0);
            }
        }
    }
}
